package com.matto1990.app.madlab.provider;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;

import com.matto1990.app.madlab.provider.MadlabContract.EventColumns;
import com.matto1990.app.madlab.provider.MadlabContract.Events;
import com.matto1990.app.madlab.provider.MadlabContract.MeetupColumns;
import com.matto1990.app.madlab.provider.MadlabContract.Meetups;
import com.matto1990.app.madlab.provider.MadlabDatabase.Tables;

public class MadlabProvider extends ContentProvider {
    private MadlabDatabase dbHelper;
    private static final UriMatcher uriMatcher = buildUriMatcher();
    
    // Values used to check which uri has been matches
    // Events
    private static final int EVENTS = 100;
    private static final int EVENTS_ID = 101;
    private static final int EVENTS_MEETUPS = 102;
    // Meetups
    private static final int MEETUPS = 200;
    private static final int MEETUPS_ID = 201;
    
    /**
     * Build and return a {@link UriMatcher} that catches all {@link Uri}
     * variations supported by this {@link ContentProvider}.
     */
    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = MadlabContract.CONTENT_AUTHORITY;
        
        matcher.addURI(authority, "events", EVENTS);
        matcher.addURI(authority, "events/*", EVENTS_ID);
        matcher.addURI(authority, "events/*/meetups", EVENTS_MEETUPS);
        
        matcher.addURI(authority, "meetups", MEETUPS);
        matcher.addURI(authority, "meetups/*", MEETUPS_ID);
        
        return matcher;
    }
    
    /**
     * Run when content provider is first created
     */
    @Override
    public boolean onCreate() {
        dbHelper = new MadlabDatabase(getContext());
        return true;
    }
    
    /**
     * Get the type of URI that has been submitted
     * 
     * @return The MIME type of the content URI submitted
     */
    @Override
    public String getType(Uri uri) {
        final int match = uriMatcher.match(uri);
        switch (match) {
        case EVENTS:
            return Events.CONTENT_TYPE;
        case EVENTS_ID:
            return Events.CONTENT_ITEM_TYPE;
        case EVENTS_MEETUPS:
            return Meetups.CONTENT_TYPE;
        case MEETUPS:
            return Meetups.CONTENT_TYPE;
        case MEETUPS_ID:
            return Meetups.CONTENT_ITEM_TYPE;
        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }
    
    /** {@inheritDoc} */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        final SQLiteDatabase db = dbHelper.getReadableDatabase();
        
        // Build a query based on URI
        final SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        final int match = uriMatcher.match(uri);
        switch (match) {
        case EVENTS:
            queryBuilder.setTables(Tables.EVENTS);
            break;
        case EVENTS_ID:
            queryBuilder.setTables(Tables.EVENTS);
            queryBuilder.appendWhere(EventColumns.EVENT_ID + "=\"" + Events.getEventId(uri) + "\"");
            break;
        case EVENTS_MEETUPS:
            queryBuilder.setTables(Tables.MEETUPS_EVENT_JOIN);
            queryBuilder.appendWhere(EventColumns.EVENT_ID + "=\"" + Events.getEventId(uri) + "\"");
            break;
        case MEETUPS:
            queryBuilder.setTables(Tables.MEETUPS_EVENT_JOIN);
            break;
        case MEETUPS_ID:
            queryBuilder.setTables(Tables.MEETUPS_EVENT_JOIN);
            queryBuilder.appendWhere(MeetupColumns.MEETUP_ID + "=\"" + Meetups.getMeetupId(uri) + "\"");
        }
        
        return queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
    }
    
    /** {@inheritDoc} */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        final SQLiteDatabase db = dbHelper.getReadableDatabase();
        
        // Match the URI and insert the data. Then return the URI of that new data
        final int match = uriMatcher.match(uri);
        switch (match) {
        case EVENTS:
            db.insertOrThrow(Tables.EVENTS, null, values);
            return Events.buildEventUri(values.getAsString(Events.EVENT_ID));
        case MEETUPS:
            db.insertOrThrow(Tables.MEETUPS, null, values);
            return Meetups.buildMeetupUri(values.getAsString(Meetups.MEETUP_ID));
        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }
    
    /** {@inheritDoc} */
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        final SQLiteDatabase db = dbHelper.getReadableDatabase();
        
        // Match the URI and perform the update
        final int match = uriMatcher.match(uri);
        switch (match) {
        case EVENTS_ID:
            if (selection == null) {
                selection = Events.EVENT_ID + "=\"" + Events.getEventId(uri) +"\"";
            }
            return db.update(Tables.EVENTS, values, selection, selectionArgs);
        case MEETUPS_ID:
            if (selection == null) {
                selection = Meetups.MEETUP_ID + "=\"" + Meetups.getMeetupId(uri) +"\"";
            }
            return db.update(Tables.MEETUPS, values, selection, selectionArgs);
        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }
    
    /** {@inheritDoc} */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        final SQLiteDatabase db = dbHelper.getReadableDatabase();
        
        // Match the RUI and perform the delete
        final int match = uriMatcher.match(uri);
        switch (match) {
        case EVENTS_ID:
            return db.delete(Tables.EVENTS, selection, selectionArgs);
        case MEETUPS_ID:
            return db.delete(Tables.MEETUPS, selection, selectionArgs);
        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }
}
